<template>
  <el-dialog
    v-model="showImageUploadDialogFlag"
    :title="dialogTitle"
    left
    :append-to-body="true"
    class="drag-dialog small-padding-dialog"
    width="90%"
    :before-close="closeDialog"
    :close-on-click-modal="false"
    destroy-on-close
    align-center
  >
    <el-upload
      ref="upload"
      :auto-upload="false"
      class="upload-demo"
      :show-file-list="false"
      :accept="VideoFormat"
      v-model:file-list="fileList"
      action="#"
      drag
      multiple="true"
      :on-change="handleChange"
      v-if="!saved"
    >
      <el-icon class="el-icon--upload">
        <upload-filled />
      </el-icon>
      <div class="el-upload__text">拖拽文件到这里或者<em>点击上传</em></div>
      <div class="el-upload__tip">
        支持格式：{{ VideoFormatStr }}，视频大小不超过{{ VideoSize }}M
      </div>
    </el-upload>
    <div style="margin-top: 10px" v-if="saved">
      <div class="block-left" id="left">
        <el-form :model="videoForm" label-width="80px" ref="videoFormRef">
          <el-row>
            <el-col :span="12">
              <el-form-item
                label="资源标题"
                :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源标题' }"
                prop="name"
              >
                <el-input v-model="videoForm.name" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="批次编号" prop="batch">
                <el-input v-model="videoForm.batch" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="DOI">
                <el-input v-model="videoForm.doi" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="视频来源">
                <el-input v-model="videoForm.source" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="视频标签">
                <el-select v-model="videoForm.label" placeholder="请选择视频标签">
                  <el-option
                    v-for="item in labelList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="视频分类">
                <el-select v-model="videoForm.classify" placeholder="请选择视频分类">
                  <el-option
                    v-for="item in classifyList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="作者">
                <el-input v-model="videoForm.author" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="用途">
                <el-input v-model="videoForm.useTo" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="发布时间">
                <el-date-picker
                  v-model="videoForm.releaseTime"
                  type="date"
                  placeholder="请选择发布时间"
                  :disabled-date="disabledDate"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="密级">
                <el-select v-model="videoForm.secret" placeholder="请选择密级">
                  <el-option
                    v-for="item in secretList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="拍摄时间">
                <el-date-picker
                  v-model="videoForm.captureTime"
                  type="date"
                  placeholder="请选择拍摄时间"
                  :disabled-date="disabledDate"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="相关地点">
                <el-input v-model="videoForm.place" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="封面">
                <el-upload
                  :file-list="fileList"
                  :action="UPLOAD_URL"
                  :headers="HEADERS"
                  multiple="false"
                  :limit="1"
                  list-type="picture-card"
                  :auto-upload="true"
                  :before-upload="onBeforeUpload"
                  :on-error="onUploadError"
                  :on-success="onUploadSuccess"
                >
                  <el-icon>
                    <Plus />
                  </el-icon>
                  <template #file="{ file }">
                    <div>
                      <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
                      <span class="el-upload-list__item-actions">
                        <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                          <el-icon><Delete /></el-icon>
                        </span>
                      </span>
                    </div>
                  </template>
                </el-upload>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="描述">
                <el-input type="textarea" v-model="videoForm.remark" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="标记">
                <el-input type="textarea" v-model="videoForm.mark" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="关键帧">
                <el-image
                  v-if="keyframes.length > 0"
                  style="max-width: 150px; max-height: 150px; margin-right: 5px"
                  :preview-src-list="keyframes"
                  :initial-index="index"
                  v-for="(item, index) in keyframes"
                  :key="item"
                  :src="item"
                />
                <!-- <span v-else class="description-text"> 暂无关键帧 </span> -->
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <div class="block-right">
        <el-progress
          type="dashboard"
          v-if="showProgress"
          :percentage="percentage"
          width="200"
          :indeterminate="true"
        >
          <template #default="{ percentage }">
            <span class="percentage-value">{{ percentage }}%</span>
            <span class="percentage-label">{{ uploadTitle }}</span>
          </template>
        </el-progress>
        <div class="videoBox">
          <video
            crossOrigin="anonymous"
            id="videoJs"
            class="video-js vjs-default-skin"
            autoplay
            style="width: 100%; height: 100%; object-fit: fill"
          ></video>
        </div>
        <!--        <video-player-->
        <!--          v-if="videoForm.url"-->
        <!--          class="video-player vjs-big-play-centered videoBox"-->
        <!--          :src="videoForm.url"-->
        <!--          poster=""-->
        <!--          crossorigin="Anonymous"-->
        <!--          controls-->
        <!--          playsinline-->
        <!--          :volume="0.6"-->
        <!--          :playback-rates="[0.7, 1.0, 1.5, 2.0]"-->
        <!--          :height="500"-->
        <!--        />-->
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <span v-if="saved" style="display: block; margin-bottom: 10px; color: red">{{
          prompt
        }}</span>
        <el-button type="primary" @click="closeDialog">关闭</el-button>
        <el-button type="primary" v-if="!isSaveForm" :disabled="!saved" @click="saveForm"
          >保存</el-button
        >
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { VideoFormatStr, VideoSize, VideoFormat } from '@/utils/config'
import { Delete, Plus } from '@element-plus/icons-vue'
import * as videoApi from '@/api/video'
import { type UploadProps, FormInstance, UploadRawFile } from 'element-plus'
import { reactive, ref } from 'vue'
import 'video.js/dist/video-js.css'
import { generateUUID } from '@/utils'
import { getAccessToken } from '@/utils/auth'
import { UploadType, useBeforeUpload } from '@/views/mp/hooks/useUpload'
import 'video.js/dist/video-js.css'
import videojs from 'video.js'
import type { UploadFile } from 'element-plus'
import { propTypes } from '@/utils/propTypes'

const props = defineProps({
  pid: Number,
  animation: Boolean,
  type: Number
})

const UPLOAD_URL = import.meta.env.VITE_BASE_URL + '/admin-api/video/cover/upload'
const HEADERS = { Authorization: 'Bearer ' + getAccessToken() }
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const fileList = ref([])
const saved = ref(false)
const videoForm = ref({})
const videoHeight = ref(0)
const uploadTitle = ref('')
const showProgress = ref(true)

const classifyList = ref([])
const labelList = ref([])
const showImageUploadDialogFlag = ref(false)
const dialogTitle = ref('视频上传')
const prompt = ref<string>()
// 分块大小20MB
const chunkSize = 1024 * 1024 * 20

const videoFormRef = ref<FormInstance>()

const percentage = ref(0)
const videoShow = ref(false)

const handleChange: UploadProps['onChange'] = async (uploadFile, uploadFiles) => {
  saved.value = true
  showProgress.value = true
  //uploadTitle.value = '正在计算文件MD5'
  let md5 = generateUUID()
  let fileName = uploadFile.name
  uploadFile.md5 = md5
  const fileSize = uploadFile.size || 0
  let chunkTotals = Math.ceil(fileSize / chunkSize)
  let percents = 0
  uploadTitle.value = '正在上传'
  if (chunkTotals > 1) {
    for (
      let chunkNumber = 0, start = 0;
      chunkNumber < chunkTotals;
      chunkNumber++, start += chunkSize
    ) {
      let end = Math.min(fileSize, start + chunkSize)
      // uploadFile.raw这个是element plus 中 el-upload的自己上传的文件就放在这个raw里面，可以console.log(uploadFile)看一下
      // 加 ？是因为ts语法提示“uploadFile.raw”可能为“未定义”，加了这个就不过有报错了
      const files = uploadFile.raw?.slice(start, end)
      let form = new FormData()
      form.append('chunkNumber', chunkNumber + 1)
      form.append('chunkTotal', chunkTotals)
      form.append('fileName', uploadFile.name)
      form.append('file', files)
      form.append('fileMD5', md5)
      const result = await videoApi.uploadChunk(form)
      if (result.data) {
        console.log(percents)
        percents = percents + (1 / chunkTotals).toFixed(2) * 100
        if (chunkNumber == chunkTotals - 1) {
          percents = 100
          uploadTitle.value = '上传成功'
        }
        uploadFile.percentage = percents
        percentage.value = percents
      }
    }
    let video = await videoApi.merge(md5, chunkTotals, uploadFile.size, fileName.split('.').pop())
    const thumb = ref({})
    thumb.value.url = video.thumb
    fileList.value.push(thumb.value)
    showProgress.value = false
    videoForm.value = video
  } else if (chunkTotals == 1) {
    let form = new FormData()
    form.append('file', uploadFile.raw)
    const result = await videoApi.upload(form)
    const thumb = ref({})
    thumb.value.url = result.data.thumb
    fileList.value.push(thumb.value)
    showProgress.value = false
    videoForm.value = result.data
  }
  options.sources?.push({
    src: videoForm.value.url,
    type: videoForm.value.url.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'
  })
  player = videojs('videoJs', options, () => {
    player.play()
  })
  videoForm.value.name = uploadFile.name
}

const deleteFileByFileName = async (md5: any) => {
  console.log(md5)
}
const closeDialog = () => {
  showImageUploadDialogFlag.value = false
  saved.value = false
  options.sources = []
  prompt.value = ''
  resetForm()
}
const x = () => {}
const saveForm = () => {
  videoFormRef.value.validate(async (valid) => {
    console.log(valid)
    if (valid) {
      console.log(videoForm.value)
      videoForm.value.pid = props.pid
      videoForm.value.animation = props.animation
      videoForm.value.type = props.type
      videoApi.save(videoForm.value).then((res) => {
        resetForm()
        showImageUploadDialogFlag.value = false
        getList()
      })
    }
  })
}
const keyframes = ref([])
const formType = ref('')
const isSaveForm = ref(false)
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
let player
const openDialog = async (type: string, id?: number) => {
  showImageUploadDialogFlag.value = true
  classifyList.value = await videoApi.getVideoClassify()
  labelList.value = await videoApi.getVideoLabel()
  formType.value = type
  if (id) {
    try {
      showProgress.value = false
      saved.value = true
      formLoading.value = true
      if (formType.value == 'update') {
        videoForm.value = await videoApi.selectOne(id)
      } else if (formType.value == 'deleted') {
        videoForm.value = await videoApi.selectDeleted(id, 1)
        isSaveForm.value = true
      }
      options.sources?.push({
        src: videoForm.value.url,
        type: videoForm.value.url.endsWith('.m3u8') ? 'application/x-mpegURL' : 'video/mp4'
      })
      player = videojs('videoJs', options, () => {
        player.play()
      })
      const keyframes1 = videoForm.value.keyframes
      keyframes.value = JSON.parse(keyframes1)
      const thumb = ref({})
      thumb.value.url = videoForm.value.thumb
      fileList.value.push(thumb.value)
    } finally {
      formLoading.value = false
    }
  } else {
    prompt.value = '注：点击保存后自动提取视频关键帧并进行视频转码。'
  }
}
const options: videojs.PlayerOptions = reactive({
  autoplay: true, // true,浏览器准备好时开始播放。
  muted: true, // 默认情况下将会消除音频。
  loop: true, // 导致视频一结束就重新开始。
  controls: true, //取消视频中的进度条
  preload: 'auto', // auto浏览器选择最佳行为,立即开始加载视频（如果浏览器支持）
  language: 'zh-CN', //汉化
  fluid: true, // 当true时，将按比例缩放以适应其容器。
  sources: [
    {
      type: '',
      src: '' //视频播放地址
    }
  ],
  notSupportedMessage: '此视频暂无法播放，请稍后再试', // 无法播放媒体源时显示的默认信息。
  textTrackDisplay: false
})
const resetForm = () => {
  console.log(saved.value)
  if (saved.value) {
    player.dispose()
  }
  saved.value = false
  showProgress.value = true
  videoForm.value = {}
  fileList.value = []
  keyframes.value = []
}
const getList: any = inject('getList')

const handleRemove = (file: UploadFile) => {
  fileList.value = []
}
const onBeforeUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) =>
  useBeforeUpload(UploadType.Image, 10)(rawFile)

const onUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
  if (res.code !== 0) {
    message.error('上传出错：' + res.msg)
    return false
  }
  videoForm.value.thumb = res.data
}
const onUploadError = (err: Error) => {
  message.error('上传失败: ' + err.message)
}
defineExpose({
  openDialog
})
</script>
<style lang="scss" scoped>
.block-left {
  display: inline-block;
  width: 70%;
  padding: 30px 20px;
  text-align: center;
  vertical-align: top;
  border-right: solid 1px var(--el-border-color);
  box-sizing: border-box;
}

.block-right {
  display: inline-block;
  width: 30%;
  padding: 30px 20px;
  text-align: center;
  vertical-align: top;
  border-right: solid 1px var(--el-border-color);
  box-sizing: border-box;
}

.dialog-footer {
  text-align: center;
}

.body {
  margin: 0;
}

.demo-image__error .block {
  display: inline-block;
  width: 20%;
  height: 330px;
  padding: 30px 20px;
  text-align: center;
  vertical-align: top;
  border-right: solid 1px var(--el-border-color);
  box-sizing: border-box;
}

.demo-image__error .block .more {
  float: right;
  color: #8c8a8a;
}

.demo-image__error .demonstration {
  display: block;
  margin-top: 10px;
  margin-bottom: 20px;
  font-size: 14px;
  color: var(--el-text-color-secondary);
  text-align: left;
}

.demo-image__error .datetime {
  display: block;
  margin-top: 10px;
  font-size: 14px;
  color: #666;
  text-align: left;
}

.demo-image__error .checkbox {
  display: block;
  margin-bottom: 10px;
  font-size: 14px;
  text-align: left;
}

.demo-image__error .el-image {
  width: 100%;
  height: 100%;
  max-width: 300px;
  max-height: 200px;
}

.demo-image__error .image-slot {
  display: flex;
  width: 100%;
  height: 100%;
  font-size: 30px;
  color: var(--el-text-color-secondary);
  background: var(--el-fill-color-light);
  justify-content: center;
  align-items: center;
}

.demo-image__error .image-slot .el-icon {
  font-size: 30px;
}

.option {
  display: flex;
  float: right;
  color: #8c8e91;
  cursor: pointer;
  align-items: center;
}

.videoBox {
  //  object-fit: fill;
  width: 100%;
}
</style>
